package org.springblade.upgrade.controller;

import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.api.R;
import org.springblade.upgrade.config.entity.PackageBackendConfig;
import org.springblade.upgrade.config.service.IPackageBackendConfigService;
import org.springblade.upgrade.constant.PortConstant;
import org.springblade.upgrade.nacos.NacosServer;
import org.springblade.upgrade.nacos.model.NacosInstanceInfo;
import org.springblade.upgrade.nacos.model.NacosServerInfo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


@RestController()
@Slf4j
@RequestMapping("/nacos")
public class UpgradeController {

    @Resource
    private NacosServer nacosServer;
    @Resource
    private IPackageBackendConfigService packageBackendConfigService;
    //工程状态
    private static Map<String, List<NacosInstanceInfo>> serverCache = new HashMap<>();
    //定时作业
    private static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);

    @PostConstruct
    public void init() {
//        log.error("工程状态,初始化》》");
//        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
//            @Override
//            public void run() {
//                refreshProjectState();
//            }
//        }, 15, 15, TimeUnit.MINUTES);
    }

    /**
     * 更新缓存
     */
    protected void refreshProjectState() {
        try {
            List<PackageBackendConfig> backendConfigs = packageBackendConfigService.list();
            if (backendConfigs == null || backendConfigs.size() == 0) {
                return;
            }
            //清理旧数据
            serverCache.clear();
            //新数据
            List<NacosInstanceInfo> instanceInfos;
            for (PackageBackendConfig backendConfig : backendConfigs) {
                if (!"Y".equalsIgnoreCase(backendConfig.getNeedMonitor())) {
                    continue;
                }
                //查询实例
                instanceInfos = nacosServer.queryInstances(backendConfig.getSysModule()).getList();
                if (instanceInfos != null) {
                    serverCache.put(backendConfig.getSysModule(), instanceInfos);
                } else {
                    serverCache.put(backendConfig.getSysModule(), Collections.emptyList());
                }
                //休眠1s
                Thread.sleep(1000);
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            log.error("异常" + ex.getMessage(), ex);
        }
    }

    /**
     * 查询各个工程状态
     */
    @GetMapping("/projectState")
    public R<Map<String, List<NacosInstanceInfo>>> projectState() {
        return R.data(serverCache);
    }

    /**
     * 查询字典
     */
    @GetMapping("/dicList")
    public R<List<Map<String, Object>>> dicList() {
        try {
            List<NacosServerInfo> dataList = nacosServer.queryServerList().getServiceList();
            List<Map<String, Object>> list = new ArrayList<>();
            if (dataList != null) {
                dataList.sort(new Comparator<NacosServerInfo>() {
                    @Override
                    public int compare(NacosServerInfo o1, NacosServerInfo o2) {
                        return o1.getName().compareTo(o2.getName());
                    }
                });
                Map<String, Object> item;
                for (NacosServerInfo data : dataList) {
                    item = new HashMap<>();
                    item.put("configId", data.getName());
                    item.put("configName", data.getName());
                    list.add(item);
                }
            }
            return R.data(list);
        } catch (Exception ex) {
            return R.fail(ex.getMessage());
        }
    }


    @GetMapping("/serverList")
    public R serverList() {
        try {
            return R.data(nacosServer.queryServerList().getServiceList());
        } catch (Exception ex) {
            ex.printStackTrace();
            return R.fail(ex.getMessage());
        }

    }


    @GetMapping("/instances")
    public R<List<NacosInstanceInfo>> instances(@RequestParam("serviceName") String serviceName) {
        try {
            if (serviceName == null || serviceName.isEmpty()) {
                return R.fail("参数不能为空！");
            }
            R<List<NacosInstanceInfo>> r = R.data(nacosServer.queryInstances(serviceName).getList());
            return r;
        } catch (Exception ex) {
            ex.printStackTrace();
            return R.fail(ex.getMessage());
        }

    }

    @GetMapping("/getDefaultPort")
    public R<String> getDefaultPort(@RequestParam("serviceName") String serviceName) {
        try {
            if (serviceName == null || serviceName.isEmpty()) {
                return R.data("");
            }
            R<List<NacosInstanceInfo>> r = R.data(nacosServer.queryInstances(serviceName).getList());
            if (r == null || !r.isSuccess()) {
                return R.data(PortConstant.getPort(serviceName));
            }
            List<NacosInstanceInfo> dataList = r.getData();
            if (dataList == null || dataList.size() == 0 || dataList.size() > 1) {
                return R.data(PortConstant.getPort(serviceName));
            }
            String port = dataList.get(0).getPort();
            if (port == null || port.trim().length() == 0) {
                return R.data(PortConstant.getPort(serviceName));
            }
            port = port.trim();
            if (port.startsWith("1")) {
                return R.data("2" + port.substring(1));
            } else {
                return R.data("1" + port.substring(1));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return R.fail(ex.getMessage());
        }

    }


    @GetMapping("/enable")
    public R<String> enable(NacosInstanceInfo cond) {
        try {
            return nacosServer.updateEnable(cond, true);
        } catch (Exception ex) {
            ex.printStackTrace();
            return R.fail(ex.getMessage());
        }

    }

    @GetMapping("/unable")
    public R<String> unable(NacosInstanceInfo cond) {
        try {
            return nacosServer.updateEnable(cond, false);
        } catch (Exception ex) {
            ex.printStackTrace();
            return R.fail(ex.getMessage());
        }

    }
}
